package main

import (
	geeD1 "dingusxp/trial/gee/d1/gee"
	geeD2 "dingusxp/trial/gee/d2/gee"
	geeD3 "dingusxp/trial/gee/d3/gee"
	geeD4 "dingusxp/trial/gee/d4/gee"
	geeD5 "dingusxp/trial/gee/d5/gee"
	geeD6 "dingusxp/trial/gee/d6/gee"
	geeD7 "dingusxp/trial/gee/d7/gee"
	"flag"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"strings"
	"time"
)

const addr = "0.0.0.0:8080"
const defaultCase = "d7"

var runCase = flag.String("case", defaultCase, "which case for running: d1-d7")

func main() {

	flag.Parse()
	switch *runCase {
	case "d7", "D7", "7":
		runD7()
	case "d6", "D6", "6":
		runD6()
	case "d5", "D5", "5":
		runD5()
	case "d4", "D4", "4":
		runD4()
	case "d3", "D3", "3":
		runD3()
	case "d2", "D2", "2":
		runD2()
	default:
		runD1()
	}
}

func runD1() {

	gee := geeD1.New()
	gee.Get("/", func(rw http.ResponseWriter, r *http.Request) {

		result := []byte(`{"code":0, "message": "OK", "result":null}`)
		rw.Header().Add("Content-Type", "application/json")
		rw.Write(result)
	})
	gee.Get("/say", func(rw http.ResponseWriter, r *http.Request) {

		name := r.URL.Query().Get("name")
		if len(name) == 0 {
			name = "NoName"
		}
		result := []byte(fmt.Sprintf(`{"code":0, "message": "OK", "result":{"message": "hello %s"}}`, name))
		rw.Header().Add("Content-Type", "application/json")
		rw.Write(result)
	})
	gee.Run(addr)
}

func runD2() {

	gee := geeD2.New()
	gee.Get("/", func(c *geeD2.Context) {
		c.JSON(geeD2.H{
			"code":    0,
			"message": "OK",
			"result":  nil,
		})
	})
	gee.Get("/say", func(c *geeD2.Context) {
		name := c.Get("name")
		if len(name) == 0 {
			name = "NoName"
		}
		c.JSON(geeD2.H{
			"code":    0,
			"message": "OK",
			"result":  geeD2.H{"message": fmt.Sprintf("hello, %s", name)},
		})
	})
	gee.Run(addr)
}

func runD3() {

	gee := geeD3.New()
	gee.Get("/", func(c *geeD3.Context) {
		c.JSON(geeD3.H{
			"code":    0,
			"message": "OK",
			"result":  nil,
		})
	})
	gee.Get("/hello/:name", func(c *geeD3.Context) {
		name := c.Param("name")
		msg := c.Get("msg")
		c.JSON(geeD3.H{
			"code":    0,
			"message": "OK",
			"result":  geeD3.H{"message": fmt.Sprintf("hello, %s %s", name, msg)},
		})
	})
	gee.Get("/api/:controller/:action", func(c *geeD3.Context) {
		controller := c.Param("controller")
		action := c.Param("action")
		c.JSON(geeD3.H{
			"code":    0,
			"message": "OK",
			"result":  geeD3.H{"controller": controller, "action": action},
		})
	})
	gee.Get("/static/*staticFile", func(c *geeD3.Context) {
		file := c.Param("staticFile")
		c.JSON(geeD3.H{
			"code":    0,
			"message": "OK",
			"result":  geeD3.H{"file": file},
		})
	})
	gee.Run(addr)
}

func runD4() {

	gee := geeD4.New()
	gee.Get("/", func(c *geeD4.Context) {
		c.JSON(geeD4.H{
			"code":    0,
			"message": "OK",
			"result":  nil,
		})
	})
	g1 := gee.Group("/user")
	{
		g1.Get("/:name/info", func(c *geeD4.Context) {
			name := c.Param("name")
			c.JSON(geeD4.H{
				"code":    0,
				"message": "OK",
				"result":  geeD4.H{"user": name},
			})
		})
		g1.Get("/list", func(c *geeD4.Context) {
			c.JSON(geeD4.H{
				"code":    0,
				"message": "OK",
				"result":  "userlist...",
			})
		})
	}
	g2 := gee.Group("/static")
	{
		g2.Get("/css/*file", func(c *geeD4.Context) {
			file := c.Param("file")
			c.JSON(geeD4.H{
				"code":    0,
				"message": "OK",
				"result":  strings.Join([]string{"css file: ", file}, "/"),
			})
		})
		g2.Get("/js/*file", func(c *geeD4.Context) {
			file := c.Param("file")
			c.JSON(geeD4.H{
				"code":    0,
				"message": "OK",
				"result":  strings.Join([]string{"js file: ", file}, "/"),
			})
		})
	}
	gee.Run(addr)
}

func runD5() {

	gee := geeD5.New()
	gee.Use(func(c *geeD5.Context) {
		start := time.Now()
		c.Next()
		cost := time.Since(start)
		log.Printf("handled path %s - status:%d; cost: %s\n", c.Path, c.Status, cost.String())
	})
	gee.Get("/", func(c *geeD5.Context) {
		c.JSON(geeD5.H{
			"code":    0,
			"message": "OK",
			"result":  nil,
		})
	})
	g1 := gee.Group("/user")
	{
		g1.Use(func(c *geeD5.Context) {
			c.Params["auth"] = "d5"
		})
		g1.Get("/:name/info", func(c *geeD5.Context) {
			name := c.Param("name")
			auth := c.Param("auth")
			c.JSON(geeD5.H{
				"code":    0,
				"message": "OK",
				"result":  geeD5.H{"user": name, "auth": auth},
			})
		})
	}
	g2 := gee.Group("/api")
	{
		g2.Use(func(c *geeD5.Context) {
			name := c.Get("name")
			if name == "fuck" {
				c.HTML("<h2>Bad words!</h2>")
				c.Abort()
			}
		})
		g2.Get("/sayHello", func(c *geeD5.Context) {
			name := c.Get("name")
			if name == "" {
				name = "world"
			}
			c.JSON(geeD5.H{
				"code":    0,
				"message": "OK",
				"result":  fmt.Sprintf("hello %s", name),
			})
		})
	}
	gee.Run(addr)
}

func runD6() {

	gee := geeD6.New()
	gee.Use(func(c *geeD6.Context) {
		start := time.Now()
		c.Next()
		cost := time.Since(start)
		log.Printf("handled path %s - status:%d; cost: %s\n", c.Path, c.Status, cost.String())
	})
	gee.LoadTemplates("tpl/*", template.FuncMap{})
	g := gee.Group("/static")
	{
		g.Static("/css", "./static/css")
		g.Static("/img", "./static/img")
	}
	gee.Get("/", func(c *geeD6.Context) {
		c.Tpl("index.tmpl", geeD6.H{
			"title": "Hello D6 Server",
		})
	})
	g2 := gee.Group("/api")
	{
		g2.Use(func(c *geeD6.Context) {
			name := c.Get("name")
			if name == "fuck" {
				c.JSON(geeD6.H{
					"code":    1,
					"message": "Bad words!",
					"result":  nil,
				})
				c.Abort()
			}
		})
		g2.Get("/sayHello", func(c *geeD6.Context) {
			name := c.Get("name")
			if name == "" {
				name = "world"
			}
			c.JSON(geeD6.H{
				"code":    0,
				"message": "OK",
				"result":  fmt.Sprintf("hello %s", name),
			})
		})
	}
	gee.Run(addr)
}

func runD7() {

	gee := geeD7.Default()
	gee.LoadTemplates("tpl/*", template.FuncMap{})
	gee.Static("/static", "./static")
	gee.Get("/", func(c *geeD7.Context) {
		c.Tpl("index.tmpl", geeD7.H{
			"title": "Hello D7 Server",
		})
	})
	g2 := gee.Group("/api")
	{
		g2.Use(func(c *geeD7.Context) {
			name := c.Get("name")
			if name == "fuck" {
				c.JSON(geeD7.H{
					"code":    1,
					"message": "Bad words!",
					"result":  nil,
				})
				c.Abort()
			}
		})
		g2.Get("/sayHello", func(c *geeD7.Context) {
			name := c.Get("name")
			if name == "" {
				name = "world"
			}
			if name == "bug" {
				panic("oh, here is a bug.")
			}
			c.JSON(geeD7.H{
				"code":    0,
				"message": "OK",
				"result":  fmt.Sprintf("hello %s", name),
			})
		})
	}
	geeD7.PprofWrapEngine(gee)
	gee.Run(addr)
}
